package com.wanghua.mall.auth.controller;

import com.alibaba.fastjson.JSON;
import com.wanghua.common.utils.R;
import com.wanghua.common.utils.RandomUtils;
import com.wanghua.mall.auth.vo.LoginVo;
import com.wanghua.mall.auth.vo.RegisterVo;
import com.wanghua.mall.auth.openfeign.SmsClient;
import com.wanghua.mall.auth.openfeign.UserClient;
import com.wanghua.common.vo.UserResponseVo;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author wanghua
 * @create 2021-09-05 16:10
 */
@Controller
public class LoginController {
    @Resource
    SmsClient smsClient;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private UserClient userClient;

    @ResponseBody
    @PostMapping("/sendMessage")
    public R sendMessage(@RequestParam("phone") String phone) {
        String code;
        //TODO 设置多次获取验证码的间隔时间，防止恶意发短信
        //Redis里有数据就不发送短信
        code = redisTemplate.opsForValue().get(phone);
        if (StringUtils.hasLength(code)) {
            System.out.println("从缓存中获取code:" + code);
            return R.ok().put("code", code);
        }
        //Redis里没有数据就发送短信
        code = RandomUtils.getSixBitRandom();
        R r = smsClient.sendMessage(phone, code);
        if ("Ok".equals(r.get("status"))) {
            redisTemplate.opsForValue().set(phone, code, 30, TimeUnit.MINUTES);
            return R.ok().put("code", code);
        } else {
            return R.error();
        }
    }

    //注册
    //RedirectAttributes可以通过session保存信息并在重定向的时候携带过去
    @PostMapping("/register")
    public String register(@Valid RegisterVo registerVo, BindingResult result, RedirectAttributes redirectAttributes) {
        //1.判断校验是否通过
        Map<String, String> errors;
        if (!result.hasErrors()) {
            //2.若JSR303校验通过
            //判断验证码是否正确
            String code = redisTemplate.opsForValue().get(registerVo.getPhone());
            if (StringUtils.hasLength(code) && code.equals(registerVo.getCode())) {
                //远程调用
                R r = userClient.register(registerVo);
                if (r.getCode() == 0) {
                    //成功
                    return "redirect:http://auth.mall.com/login.html";
                } else {
                    errors = new HashMap<>();
                    errors.put("msg", (String) r.get("msg"));
                    redirectAttributes.addFlashAttribute("errors", errors);
                    return "redirect:http://auth.mall.com/register.html";
                }
            }
        } else {
            //出错
            errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, DefaultMessageSourceResolvable::getDefaultMessage));
            redirectAttributes.addFlashAttribute("errors", errors);
            //如果校验出错,重定向到注册页(转发会重复提交表单)
            return "redirect:http://auth.mall.com/register.html";
        }
        return "redirect:http://auth.mall.com/register.html";

    }

    @PostMapping("/login")
    public String login(@Valid LoginVo loginVo, HttpSession httpSession, RedirectAttributes redirectAttributes) {
        R r = userClient.login(loginVo);
        if (r.getCode() == 0) {
            //登录成功
            UserResponseVo loginUser = JSON.parseObject((String) r.get("data"), UserResponseVo.class);
            System.out.println(loginUser);
            httpSession.setAttribute("loginUser", loginUser);
            return "redirect:http://mall.com";
        } else {
            Map<String, String> errors = new HashMap<>();
            errors.put("msg", (String) r.get("msg"));
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.mall.com/login.html";
        }

    }
}
